home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / HWGPOST / hwgpostlib.doc < prev    next >
Text File  |  1996-10-26  |  23KB  |  561 lines

  1. PostScript shared library interface (post.library, with HWGPOST >= V22.26)
  2. ==========================================================================
  3.  
  4. HWGPOST, Copyright 1993-96 Heinz Wrobel, is mostly calling
  5. compatible to Post V1.7, Copyright Adrian Aylward 1991, 1992. But it
  6. is a very different beast inside.
  7.  
  8. This document is derived from Adrian Aylward's post.library
  9. documentation. It contains many comments on HWGPOST, developers should
  10. read, especially those developers who are familiar with the old
  11. post.library 1.7.
  12.  
  13.  
  14. Introduction
  15. ============
  16.  
  17. The file "post.library" is an AmigaOS Exec shared library containing a
  18. mostly Level II compliant PostScript interpreter. It is designed to
  19. be shareable between different processes, supporting arbitrarily many
  20. PostScript activations - at least until you run out of memory.
  21.  
  22. This file should be read in conjunction with the header file
  23. "postlib.h".
  24.  
  25. The standard user interface source files are distributed with the old
  26. Post 1.7. Read them as examples for now. If there is different
  27. information in this document or the current headerfile postlib.h or
  28. init.ps, the current information holds.
  29.  
  30.  
  31. Activation Records
  32. ==================
  33.  
  34. Simultaneous multiple activations of PostScript are allowed.  Before
  35. using post.library you must first open it by a call to OpenLibrary().
  36. To create an activation you then call PScreateact() which returns a
  37. pointer to the activation record.  You can then make calls to the
  38. interpreter library, passing the activation record pointer as an
  39. argument.  You can create several activations, possibly from different
  40. processes and intermingle the interpreter calls if you wish. But you
  41. CANNOT PASS ACTIVATION RECORDS BETWEEN PROCESSES! When you have
  42. finished with an activation, call PSdeleteact() to delete it and free
  43. the memory it used. Do not free bitmap memory or filehandles before
  44. freeing the activation record! When you have finished with the library
  45. call CloseLibrary(); if no other processes have it open, then Exec can
  46. remove it from memory if the space is needed.
  47.  
  48. N.B. the library can only be called from a process, as it calls
  49. various AmigaDOS functions.  IT IS NOT PERMISSIBLE TO PASS ACTIVATION
  50. RECORDS BETWEEN PROCESSES! NOTE THIS WELL!
  51.  
  52.  
  53. The Parameter Block
  54. ===================
  55.  
  56. The parameter block is the argument to PScreateact().  It specifies
  57. the addresses of the bitmap planes, size of the page, and the amount
  58. of memory to be allocated for the activation etc ...  Its format is
  59. defined in detail in the header file postlib.h.
  60.  
  61. N.B. all ints are 32 bits, shorts are 16 bits.
  62.  
  63. The page size is limited to 30000 pixels a side.  The densities
  64. (pixels per inch) may be any strictly positive integer value.  The y
  65. direction may be set to +1 - if the bitmap rows are in PostScript
  66. order (bottom row first) or -1 - Amiga order (top row first).
  67.  
  68.     page.buf[24]        Bitplane pointers, up to 24
  69.     page.len            Size in bytes of each plane
  70.     page.depth          Number plane pointers to use
  71.     page.flags          Special device options
  72.     page.bitspercolor   How many plane pointers to be used per gun.
  73.     page.PSextdevice    An optional extension to the device information
  74.     page.xbytes         Number of bytes in each row
  75.     page.xsize          Number of pixels in each row
  76.     page.ysize          Number of rows
  77.     page.ybase          Base of current band
  78.     page.yheight        Total height of full page, for band rendering
  79.     page.xden           X density
  80.     page.yden           Y density
  81.     page.ydir           Y direction
  82.  
  83. To specify how many bitplanes are used per color, you set
  84. "bitspercolor" to the appropriate value. If this value is not set, one
  85. bitplane per color is assumed and only 1, 3, and 4 are permissible as
  86. depth in this case. Example: RGB 3:3:2 => depth=8, bitspercolor=3.
  87. The amount of colors, i.e. the basic colorspace used by the
  88. interpreter is determined by depth and bitspercolor. The "logical"
  89. colordepth derived from these values may be 1, 3, or 4,
  90. representing B&W, RGB, RGBW/CMYK, respectively.
  91.  
  92. Note that bitspercolor should not exceed 8.
  93.  
  94. For special use, the page device description can be enhanced by
  95. setting page.PSextdevice. The PSextdevice structure
  96. currently contains the following fields.
  97.  
  98.     flags               Extension of the main flags field.
  99.  
  100.     maskbuf             If set, must be a plane as in page.buf. For
  101.                         any rendering you'll get bits set in this mask
  102.                         plane. This gives you a mask of the actually
  103.                         used places in the buffer. The mask might be
  104.                         useful for BltMaskBitMapRastPort() or some
  105.                         such. erasepage will clear this mask plane.
  106.  
  107.     Kbuf[8]             Eight additional plane pointers to allow for
  108.                         true eight bit CMYK rendering. You need to set
  109.                         the depth to a value greater 24 for these to
  110.                         be used.
  111.  
  112. The length of these structures is subject to change. Always set unused
  113. fields to zero.
  114.  
  115. As a starting point for memory sizes try the values following.  (These
  116. are defined in the header file.)  For normal PostScript programs the
  117. defaults are perfectly satisfactory.  If you specify a value of zero
  118. the default will be used instead; values less than the minimum will be
  119. increased.
  120.  
  121.     memvlen     50000   VM
  122.     memflen     60000   Font cache
  123.     memllen     15000   Path lines
  124.     memhlen     20000   Halftones
  125.     memplen     60000   Pattern cache
  126.  
  127. The user data pointer is intended to be used to identify multiple
  128. activations.  You can set it to any value you like.  The function
  129. pointers are described below.
  130.  
  131.     userdata            User data pointer
  132.     flushfunc           Flush page function pointer
  133.     copyfunc            Copy page function pointer
  134.  
  135. The standard input and output streams are the AmigaDOS file handles to
  136. be used by the interpreter for %stdin, %stdout, %stderr.  Also the
  137. standard output is used for prompts and the error output for error
  138. messages. These file handles will not be closed by the interpreter
  139. even though PostScript file objects referring to them may be closed.
  140. You should not set them to NULL/ZERO. If you don't need any input
  141. or output, set up valid NIL: filehandles!
  142.  
  143.     infh                Standard Input file handle
  144.     outfh               Standard Output file handle
  145.     errfh               Standard Error file handle
  146.  
  147. These are for backwards compatibility with the infamous "callextfunc"
  148. operator. You'll find details below. It is recommended that you
  149. don't touch these in new code.
  150.  
  151.     funcmax             Number of external functions
  152.     functab             Pointer to external function table, or zero
  153.  
  154. Anything else in the block is reserved and must be set to zero.
  155.  
  156.  
  157. Notes on the special device flags
  158. ---------------------------------
  159.  
  160. In the header file "postlib.h" you will find some flag definitions for
  161. the main flag field of the parameter page. They need more explanation.
  162.  
  163.     HWGPOST_DEVx_NOSHADE
  164.  
  165.         Halftoning is in effect suppressed. No halftone screens will
  166.         be used. Any color intensity that would cause shading will be
  167.         rendered as the next lower color value truly representable
  168.         within the bitplanes would. Shading is simply turned off.
  169.         This increases rendering speed.
  170.  
  171.     HWGPOST_DEVx_CMYK
  172.  
  173.         post.library supports the CMYK color space and operators.
  174.         When converting any colors to values passed to the transfer
  175.         functions, it creates RGBW values, though, instead of CMYK.
  176.         With this flag set, the colorspace mapping algorithm will stay
  177.         with CMYK and CMYK will be passed to the transfer functions if
  178.         applicable.
  179.  
  180.     HWGPOST_DEVx_INVERTOUTPUT
  181.  
  182.         The output of the transfer functions represent the value that
  183.         should be rendered into the bitplanes. With this flag set,
  184.         these values in the range [0.0;1.0] will effectively reversed
  185.         with a simple "shade = 1.0 - shade" before the rendering is
  186.         set up. This is the easiest way to create "negative" output
  187.         and might come in handy for multiple bitplane color handling,
  188.         where black should be "all bits 0" instead of "all bits 1" in
  189.         the planes. This is good for true color rendering.
  190.  
  191.  
  192. Function Pointers
  193. =================
  194.  
  195. There are two function pointers within the parameter block, which are
  196. used when the interpreter needs to call routines supplied by its
  197. client. If the pointers are NULL, the calls are skipped.
  198.  
  199. To help identify calls from multiple activations, the activation
  200. record address is also passed in A0 and the userdata pointer in A1.
  201.  
  202.       flushfunc(D0: int y1, D1: int y2)
  203.  
  204. Flush the bitmap to the screen.  The interpreter calls this function
  205. after a painting operation has updated the bitmap.  Then if the output
  206. is being viewed interactively the client can update the screen or
  207. window.  The arguments are the range of bitmap rows (y1 ... y2-1) that
  208. may have been updated.
  209.  
  210.       copyfunc(D0: int num)
  211.  
  212. Copy the page to the output device.  The argument is the value of
  213. "#copies", which should be taken into account if the output is to a
  214. printer, but is not meaningful for screen output. You should take a
  215. look at the description for PSsignalint() below, too.
  216.  
  217.  
  218. Calling External Functions
  219. ==========================
  220.  
  221. The original "callextfunc" operator of post.library <= V1.7 is no
  222. longer supported even though it is currently still available in
  223. disguise as "@callextfunc". Use of this operator is strongly
  224. discouraged as it might lure you into making assumptions about
  225. internal HWGPOST data representations.
  226.  
  227. A more general way to call external functions has been devised via the
  228. new "@calluserhook" operator. This operator collects the arguments,
  229. passes them to a "Hook" as defined by the utility.library, records any
  230. changes and returns the result. This is the calling sequence:
  231.  
  232.     mark <args..> <userhookadr> <msgadr> @calluserhook
  233.  
  234. On return the operand stack will look like this:
  235.  
  236.     mark <args..> <resint>
  237.  
  238. A number from zero to eight arguments is supported. Only certain
  239. PostScript objects may be passed as arguments: integers, reals
  240. (IEEE!), and booleans are passed as the 32 bit bitpatterns
  241. corresponding to their values; strings are passed as the 32 bit
  242. address of their contents with the length as the following 32 bit
  243. integer. (N.B. PostScript strings are terminated by length; there
  244. is no terminating null unless the program puts one there. The user
  245. function may not go beyond the string length!)
  246.  
  247. <hookadr> and <msgadr> are integers that are used as 32 bit memory
  248. address. If no <msgadr> is needed, just use 0. These addresses should
  249. be passed to the interpreter via the PSintstring() function in full
  250. PostScript notation like "/hookadr 16#780ab44 def" to be used by
  251. special PostScript code. It is advisable to put them into special,
  252. private dictionaries.
  253.  
  254. The argument values passed are put into an array of 32 bit values
  255. which is passed as "objectptr" to the Hook. The return value will be
  256. put on the operand stack as <resint> and any changes to numeric values
  257. in the 32 bit array will be put back into the args on the operand
  258. stack. The Hook may change string contents within the address and
  259. length passed to it.
  260.  
  261. As an example assume this calling sequence:
  262.  
  263.     mark 1 string1 2.5 4 string2 false hookadr 0 @calluserhook
  264.  
  265. The 32 bit array passed to the hook as object will have these
  266. contents:
  267.  
  268.     array[0]:   32 int 1
  269.     array[1]:   string1: address
  270.     array[2]:   string1: length
  271.     array[3]:   IEEE float 2.5
  272.     array[4]:   32 int 4
  273.     array[5]:   string2: address
  274.     array[6]:   string2: length
  275.     array[7]:   0
  276.  
  277. If the hook function changes array[0] to 3, array[7] to 1, and returns
  278. -1, the resulting operand stack will contain these values:
  279.  
  280.     mark 3 string1 2.5 4 string2 true -1
  281.  
  282. Changing a string address or length should not be tried. If results
  283. are not needed, a cleartomark will get rid of them easily.
  284.  
  285. There should not be any assumptions made about internal representation
  286. of objects. For booleans, only 0 and 1 should be used.
  287.  
  288. N.B. PSintstring() is not guaranteed to work recursively. So calling
  289. it from the hook is not a good idea. The Hook is called on the
  290. interpreters context. If a local near data section is needed, the Hook
  291. function is responsible for setting up A4, e.g. from hook->h_Data.
  292. Standard rules for saving registers apply. Do not assume that A4
  293. contains anything useful!
  294.  
  295.  
  296. Calling External Functions with @callextfunc
  297. ============================================
  298.  
  299. The original "callextfunc" operator of post.library <= V1.7 is no
  300. longer supported even though it is still available in disguise as
  301. "@callextfunc". Use of this operator is strongly discouraged as it
  302. might lure you into making assumptions about internal HWGPOST data
  303. representations. It is only here for limited backwards compatibility.
  304. Do not use it for new code!
  305.  
  306. If you supply an external function table your PostScript program can
  307. call the functions within it by the "@callextfunc" operator.  The
  308. contents of the table are the addresses of the function entry points.
  309. The functions must have standard (Lattice, non-registerised) C
  310. compatible calling sequences. They must not assume any useful value in
  311. register A4 on entry, and must preserve A4 and the other C registers
  312. on exit.
  313.  
  314. Unlike with post.library <= 1.7 there is additional information given,
  315. though. To help identify calls from multiple activations, the activation
  316. record address is also passed in A0 and the userdata pointer in A1.
  317.  
  318. Only certain PostScript objects may be passed as arguments: integers
  319. reals and booleans are passed as the 32 bit bitpatterns corresponding
  320. to their values; arrays and strings are passed as the 32 bit address
  321. of their contents - if the length is required it must be passed
  322. separately.  (N.B. PostScript strings are terminated by length; there
  323. is no terminating null unless the program puts one there.)
  324.  
  325. It is theoretically possible to pass arbitrary objects by including
  326. them within an array, but then you would need to know their PostScript
  327. representation. As the representation has been changed thoroughly for
  328. HWGPOST and will continue to change in the future, this "feature" is
  329. of no use at all!
  330.  
  331. The "@callextfunc" operator is only inserted into the system
  332. dictionary if a function table is present.  So you will not find it if
  333. you attempt to execute it from the standard user interface.
  334.  
  335.  
  336. Library Entry points
  337. ====================
  338.  
  339. Prototypes and pragmas for the entry points are defined in the header
  340. file.
  341.  
  342.  
  343.   Create a PostScript activation
  344.   ------------------------------
  345.  
  346.           D0:int arec = PScreateact(A1:struct PSparm *parm)
  347.  
  348. The result is the address of the new activation record.  If the
  349. activation fails an error code is returned instead - zero if the
  350. interpreter failed to start at all because there was insufficient free
  351. memory, or an interpreter error code if there was an error during
  352. initialisation. Otherwise the result is the address of the activation
  353. record.  The result is always returned as an int.  If is is greater
  354. than errmax then the activation was successful, and the value is an
  355. address; otherwise the activation failed, and the result is zero or an
  356. error code.
  357.  
  358.  
  359.   Delete a PostScript activation
  360.   ------------------------------
  361.  
  362.           VOID PSdeleteact(A0:APTR arec)
  363.  
  364. The activation record is deleted and the associated memory is freed.
  365.  
  366.  
  367.   Interpret a string or file
  368.   --------------------------
  369.  
  370.           D0:int errnum = PSintstring(A0:APTR arec, A1:char *string,
  371.                                       D0:int length, D1:int flags)
  372.  
  373.  
  374.   Flag bits:
  375.  
  376.     PSFLAGSTRING, PSFLAGGFILE, PSFLAGRUNSTDIN
  377.  
  378.         If PSFLAGSTRING is set, the contents of the string are
  379.         interpreted as PostScript source. Starting with V23.1 of
  380.         post.library, strings are treated like files internally
  381.         and they can have a maximum length of 2GB-1. If you pass
  382.         in -1 as length, the string will be assumed to be NUL
  383.         terminated. Other negative length values shoudl not be
  384.         passed in.
  385.  
  386.         If the flag PSFLAGFILE is set, the string is a file name.
  387.         Then the file's contents are interpreted.
  388.  
  389.         Starting with version 22.27, you can use PSFLAGRUNSTDIN to
  390.         make post.library  set up the input stream %stdin that you
  391.         provided as currentfile.
  392.         If neither of these flag bits are set the string is ignored,
  393.         but the other flag bits still have their effects; if more than
  394.         one is set the result is undefined.
  395.  
  396.     PSFLAGINTER
  397.  
  398.         If PSFLAGINTER is set (when interpreting a file), the file is
  399.         considered to be interactive.  The banner is printed, and the
  400.         interpreter prompts for each line of input from the file.
  401.  
  402.  
  403.     PSFLAGCLEAR
  404.  
  405.         If PSFLAGCLEAR is set, then after interpretation the operand
  406.         stack is cleared and the dictionary stack is popped until only
  407.         the system and user dictionaries remain. The execution stack
  408.         is emptied, too.
  409.  
  410.  
  411.     PSFLAGSAVE
  412.  
  413.         If PSFLAGSAVE is set, job server behaviour is set up for the
  414.         current job only. It is functionally equivalent to
  415.         (PSFLAGSTARTJOBSERVER| PSFLAGENDJOBSERVER) but you shouldn't
  416.         use the job server flags instead if you really want
  417.         PSFLAGSAVE.
  418.  
  419.         IMPORTANT: For running setup files like "init.ps", you should
  420.                    not use PSFLAGSAVE or job server flags!
  421.  
  422.  
  423.  
  424.     PSFLAGSTARTJOBSERVER, PSFLAGENDJOBSERVER
  425.  
  426.         With PSFLAGSTARTJOBSERVER and PSFLAGENDJOBSERVER one can
  427.         create one job server run, spanning multiple invocations of
  428.         PSintstring(). The former forces a successful startjob with a
  429.         "false" operand before running the job, the latter forces a
  430.         successful startjob with a "true" operand after running the
  431.         job and clears out the execution stack and does some other
  432.         private things. These flags do not nest. If you think about
  433.         using them in a tricky way: Think again and ask _first_.
  434.  
  435.         IMPORTANT: For running setup files like "init.ps", you should
  436.                    not use PSFLAGSAVE or job server flags!
  437.  
  438.  
  439.     PSFLAGERASE
  440.  
  441.         If PSFLAGERASE is set, then the page is erased.  This happens
  442.         right at the end, after any vm restore, so the page is erased
  443.         taking into account the restored transfer function(s).
  444.  
  445.  
  446. This routine is NOT guaranteed to recurse correctly; strange things or
  447. crashes may happen if you try to call it from an external function
  448. called from the same activation.
  449.  
  450.  
  451.   Signal an interrupt
  452.   -------------------
  453.  
  454.           VOID PSsignalint(A0:APTR arec, D0:int flag)
  455.  
  456. This routine may be called to set an interrupt signal flag to notify
  457. the interpreter of a special condition. The possible flag values are
  458. defined in the header file postlib.h. You may or multiple bit flags
  459. together. The interpreter tests these flags at the head of its main
  460. loop, and also within certain potentially length operators (=, ==,
  461. stack and pstack). If a flag is set it the interpreter will take
  462. appropriate action immediately and automatically clear the
  463. corresponding flag bit. You may safely call this routine at any time
  464. during the life of the activation from any task or interrupt. It is
  465. intended to be called from within your task's exception handler, if
  466. the CTRL-C break signal is set. Unlike with post.library <= V1.7 it
  467. is not possible to clear a flag once it has been set by calling
  468. this function. Only the interpreter will clear a flag bit when it
  469. is handled.
  470.  
  471. You may also call this function from the copypage callback with the
  472. PSINTSIGF_KILL flag. This will make the interpreter skip the erasepage
  473. command when doing a showpage, and allows you to obtain a generated
  474. bitmap easily. You don't need a backup bitmap then. It is advisable of
  475. course not to use PSFLAGERASE either in this case.
  476.  
  477.  
  478.   Signal a floating point error
  479.   -----------------------------
  480.  
  481.           VOID PSsignalfpe(A0:APTR arec)
  482.  
  483. This routine is somewhat obsolete. It used to be the function to
  484. call on a floating point trap and caused an immediate
  485. undefinedresult error. Since HWGPOST V22.28, the interprer runs on
  486. its own context though and there is no way for user code to see
  487. a floating point trap that would be caused by this function. Which
  488. in essence means that you may ONLY CALL THIS WITHIN A CALLBACK like
  489. copypage or flushpage. Even then, PSerror(), which is
  490. described below, may be a much better choice.
  491.  
  492.  
  493.   Error
  494.   -----
  495.  
  496.           VOID PSerror(A0:APTR arec, D0:int errnum)
  497.  
  498. This routine is intended to be called from within your own flush or
  499. copy page functions, to signal that an error ocurred.  You can also
  500. call it from an external function.  You must not call it at any other
  501. time; if you do, you will crash the machine.  It calls the PostScript
  502. error handler and never returns.  The values for the error number are
  503. defined in the header file.  It is essential that you ensure that
  504. you ONLY CALL THIS WITHIN A CALLBACK like copypage or flushpage.
  505.  
  506.  
  507.   Return a text string corresponding to an error name
  508.   ---------------------------------------------------
  509.  
  510.           D0:const char *str = PSerrstr(A0:int arec, D0:int errnum)
  511.  
  512. Converts a postscript error number to a text string.  Returns NULL if
  513. the number is out of range. This function may called from any task
  514. while the activation record is valid.
  515.  
  516.  
  517.   Change device page
  518.   ------------------
  519.  
  520.           VOID PSsetdevice(A0:APTR arec, A1:struct PSdevice *page)
  521.  
  522. Note: While "setpagedevice" is not currently available, the effects
  523.       caused by PSsetdevice() are _very_ likely to change in many ways
  524.       when the time comes. If you feel that you rely on effects other
  525.       than simply replacing the device page buffer and dimensions,
  526.       CONTACT ME NOW.
  527.  
  528. Changes the device page buffer and dimensions.  If the clip path is
  529. still set to its initial value (the whole page) it is changed to match
  530. the new page size; otherwise it is unchanged (and may therefore
  531. possibly exceed the new page size).  All the clip paths saved on the
  532. graphics stack are similarly changed.  The CTM at the topmost saved
  533. graphics state (the one returned to by a "grestoreall" when there are
  534. no active VM saves) is reset to match the new page size and density.
  535. Otherwise the CTM is not affected; you will likely want to execute
  536. "initmatrix" afterwards.
  537.  
  538. The interactions of this routine with the stack of saved graphics
  539. states are complex, leading to unexpected behaviour unless you
  540. understand exactly what is happening.  So it is safest to think twice
  541. about calling it and always call it when there are no save's or
  542. gsave's active, and then to reinitialise the CTM immediately.
  543. In other words: You better not use it. Stay away from it.
  544.  
  545. This routine should not be called from within a character build,
  546. kerning, or imaging procedure.
  547.  
  548.  
  549. Problems, Comments, and Bugs
  550. ============================
  551.  
  552. You will find my complete address in the header file "postlib.h".
  553. Contact me if you have any questions or suggestions. Don't rely on
  554. empirical programming. It is a lot faster and easier to ask than
  555. wasting time with fiddling around.
  556.  
  557. Heinz Wrobel
  558. <heinz@hwg.muc.de>
  559.  
  560. *** EOT ***
  561.